package com.gome.ocean.server.web;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gome.ocean.common.enums.CangoRspStatus;
import com.gome.ocean.common.enums.DataBaseType;
import com.gome.ocean.dao.model.cango.CangoInstances;
import com.gome.ocean.dao.model.cango.CangoResponseVO;
import com.gome.ocean.dao.model.cango.ParamsVO;
import com.gome.ocean.dao.model.datasource.DatasourceBO;
import com.gome.ocean.server.service.ICangoManagerService;
import com.gome.ocean.server.service.IDatasourceService;

@Controller
@RequestMapping("/ocean/server/deploy")
public class ServerApiController {

    private Logger LOGGER = LoggerFactory.getLogger(ServerApiController.class);

    @Autowired
    private ICangoManagerService cangoManagerService;
    @Autowired
    private IDatasourceService   datasourceService;

    @RequestMapping("/to=test")
    public ModelAndView toTests(ModelAndView mav) {
        mav.addObject("abc", "hello");
        mav.setViewName("index");
        return mav;
    }

    /**
     * 构建拼接数据源基本信息
     */
    private CangoInstances splitJointDataSource(CangoInstances cangoInce) {
        // 源始数据源
        if (DataBaseType.getDataBaseType(cangoInce.getSourceType()).equals(DataBaseType.Oracle)) {
            if (cangoInce.getSourceJDBCUrl().contains("DESCRIPTION")) {
                String ip = StringUtils
                    .substringAfter(StringUtils.substringBetween(cangoInce.getSourceJDBCUrl(), "HOST", ")"), "=")
                    .trim();
                String port = StringUtils
                    .substringAfter(StringUtils.substringBetween(cangoInce.getSourceJDBCUrl(), "PORT", ")"), "=")
                    .trim();
                String dbName = StringUtils.substringAfter(
                    StringUtils.substringBetween(cangoInce.getSourceJDBCUrl(), "SERVICE_NAME", ")"), "=").trim();
                cangoInce.setSourceHost(ip);
                cangoInce.setSourcePort(Integer.parseInt(port));
                cangoInce.setSourceDBname(dbName);
            } else {
                String[] ipPorts = StringUtils.split(StringUtils.substringAfter(cangoInce.getSourceJDBCUrl(), "@"),
                    ":");
                cangoInce.setSourceHost(ipPorts[0]);
                cangoInce.setSourcePort(Integer.parseInt(ipPorts[1].split("/")[0]));
                cangoInce.setSourceDBname(cangoInce.getSourceUserName());
            }
        } else {
            String[] ipPorts = StringUtils.split(StringUtils.substringBetween(cangoInce.getSourceJDBCUrl(), "//", "/"),
                ":");
            String dbName = StringUtils.substringAfterLast(cangoInce.getSourceJDBCUrl(), "/");
            cangoInce.setSourceHost(ipPorts[0]);
            cangoInce.setSourcePort(Integer.parseInt(ipPorts[1]));
            cangoInce.setSourceDBname(dbName);
        }
        // 目标数据源
        if (StringUtils.isNotBlank(cangoInce.getTargetJDBCUrl())) {
            if (DataBaseType.getDataBaseType(cangoInce.getTargetType()).equals(DataBaseType.Oracle)) {
                if (cangoInce.getTargetJDBCUrl().contains("DESCRIPTION")) {
                    String ip = StringUtils
                        .substringAfter(StringUtils.substringBetween(cangoInce.getTargetJDBCUrl(), "HOST", ")"), "=")
                        .trim();
                    String port = StringUtils
                        .substringAfter(StringUtils.substringBetween(cangoInce.getTargetJDBCUrl(), "PORT", ")"), "=")
                        .trim();
                    String dbName = StringUtils.substringAfter(
                        StringUtils.substringBetween(cangoInce.getTargetJDBCUrl(), "SERVICE_NAME", ")"), "=").trim();
                    cangoInce.setTargetHost(ip);
                    cangoInce.setTargetPort(Integer.parseInt(port));
                    cangoInce.setTargetDBname(dbName);
                } else {
                    String[] ipPorts = StringUtils.split(StringUtils.substringAfter(cangoInce.getTargetJDBCUrl(), "@"),
                        ":");
                    cangoInce.setTargetHost(ipPorts[0]);
                    cangoInce.setTargetPort(Integer.parseInt(ipPorts[1].split("/")[0]));
                    cangoInce.setTargetDBname(cangoInce.getTargetUserName());
                }
            } else {
                String[] ipPorts = StringUtils
                    .split(StringUtils.substringBetween(cangoInce.getTargetJDBCUrl(), "//", "/"), ":");
                String dbName = StringUtils.substringAfterLast(cangoInce.getTargetJDBCUrl(), "/");
                cangoInce.setTargetHost(ipPorts[0]);
                cangoInce.setTargetPort(Integer.parseInt(ipPorts[1]));
                cangoInce.setTargetDBname(dbName);
            }
        }
        return cangoInce;
    }

    /**
     * 创建实例
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/add")
    @ResponseBody
    public CangoResponseVO add(HttpServletRequest resquest, String params) {
        CangoResponseVO responseDto = new CangoResponseVO();
        try {
            ParamsVO paramVo = JSON.parseObject(URLDecoder.decode(params, "UTF-8"), ParamsVO.class);
            CangoInstances cangoInce = new CangoInstances();
            DatasourceBO sourceDataBO = datasourceService.findDatasourceBOById(paramVo.getSourceId());
            cangoInce.setSourceUserName(sourceDataBO.getUserName());
            cangoInce.setSourcePassword(sourceDataBO.getPassword());
            cangoInce.setSourceJDBCUrl(sourceDataBO.getJdbcUrl());
            cangoInce.setSourceType(sourceDataBO.getSourceType());
            if (paramVo.getIsRocketmq() == 0) {
                DatasourceBO targetDataBO = datasourceService.findDatasourceBOById(paramVo.getTargetId());
                cangoInce.setTargetUserName(targetDataBO.getUserName());
                cangoInce.setTargetPassword(targetDataBO.getPassword());
                cangoInce.setTargetJDBCUrl(targetDataBO.getJdbcUrl());
                cangoInce.setTargetType(targetDataBO.getSourceType());
                cangoInce.setTargetTableName(paramVo.getTargetTableName());
            } else {
                cangoInce.setTopicname(paramVo.getTopicName());
                cangoInce.setNamesrvaddr(paramVo.getNameSrvAddr());
                cangoInce.setTargetType(DataBaseType.ROCKETMQ.getTypeName());
            }
            cangoInce.setTables(paramVo.getSourceTableName());
            cangoInce.setProjectName(paramVo.getProjectName());
            cangoInce.setMoveMode(paramVo.getMoveMode());
            cangoInce.setName(paramVo.getInstanceName());
            cangoInce.setRocketMqVal(paramVo.getIsRocketmq());
            if (StringUtils.isEmpty(params)) {
                responseDto = new CangoResponseVO().setStatus(CangoRspStatus.FAILURE).setFailMsg("参数错误！");
            }
            responseDto = cangoManagerService.add(splitJointDataSource(cangoInce));
        } catch (Exception e) {
            e.printStackTrace();
            responseDto.setStatus(CangoRspStatus.FAILURE);
            responseDto.setFailMsg(ExceptionUtils.getMessage(e));
        }
        return responseDto;
    }

    /**
     * 检查实例
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/check")
    @ResponseBody
    public CangoResponseVO check(HttpServletRequest request, String instanceName) {
        CangoResponseVO responseDto = new CangoResponseVO();
        responseDto = cangoManagerService.check(instanceName);
        return responseDto;
    }

    /**
     * 启动实例
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/start")
    @ResponseBody
    public CangoResponseVO start(HttpServletRequest request, String params) {
        CangoResponseVO responseDto = new CangoResponseVO();
        JSONObject map;
        try {
            map = JSON.parseObject(URLDecoder.decode(params, "UTF-8"));
            responseDto = cangoManagerService.start(map.getString("instanceName"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return responseDto;
    }

    /**
     * 停止实例
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/stop")
    @ResponseBody
    public CangoResponseVO stop(HttpServletRequest request, String params) {
        CangoResponseVO responseDto = new CangoResponseVO();
        try {
            JSONObject map = JSON.parseObject(URLDecoder.decode(params, "UTF-8"));
            responseDto = cangoManagerService.stop(map.getString("instanceName"));
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return responseDto;
    }

    /**
     * 关闭实例
     * 
     * @param response
     * @return
     */
    @RequestMapping("/shutdown")
    @ResponseBody
    public CangoResponseVO shutdown(HttpServletResponse response) {
        CangoResponseVO responseDto = cangoManagerService.shutdown();
        return responseDto;
    }

    /**
     * 启动所有实例
     * 
     * @param response
     * @return
     */
    @RequestMapping("/startAll")
    @ResponseBody
    public CangoResponseVO startAll(HttpServletResponse response) {
        CangoResponseVO responseDto = cangoManagerService.startAll();
        return responseDto;
    }

    /**
     * 停止所有实例
     * 
     * @param response
     * @return
     */
    @RequestMapping("/stopAll")
    @ResponseBody
    public CangoResponseVO stopAll(HttpServletResponse response) {
        CangoResponseVO responseDto = cangoManagerService.stopAll();
        return responseDto;
    }

    /**
     * 清除所有
     * 
     * @param response
     * @return
     */
    @RequestMapping("/clearAll")
    @ResponseBody
    public CangoResponseVO clearAll(HttpServletResponse response) {
        CangoResponseVO responseDto = cangoManagerService.clearAll();
        return responseDto;
    }

    /**
     * 启用
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/enable")
    @ResponseBody
    public CangoResponseVO enable(HttpServletResponse response, String params) {
        CangoResponseVO responseDto = new CangoResponseVO();
        try {
            JSONObject map = JSON.parseObject(URLDecoder.decode(params, "UTF-8"));
            responseDto = cangoManagerService.enable(map.getString("instanceName"));
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return responseDto;
    }

    /**
     * 禁用
     * 
     * @param response
     * @param cangoRequestDto
     * @param result
     * @return
     */
    @RequestMapping("/disable")
    @ResponseBody
    public CangoResponseVO disable(HttpServletResponse response, String params) {
        CangoResponseVO responseDto = new CangoResponseVO();
        try {
            JSONObject map = JSON.parseObject(URLDecoder.decode(params, "UTF-8"));
            responseDto = cangoManagerService.disable(map.getString("instanceName"));
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }

        return responseDto;
    }

    // 删除实例
    @RequestMapping("/deleteSleInce")
    @ResponseBody
    public CangoResponseVO deleteSingleInstance(HttpServletRequest request, String params) {
        CangoResponseVO responseVO = new CangoResponseVO();
        try {
            JSONObject map = JSON.parseObject(URLDecoder.decode(params, "UTF-8"));
            responseVO = cangoManagerService.deleteByInstanceName(map.getString("instanceName"));
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getMessage(e));
            responseVO.setFailMsg(ExceptionUtils.getMessage(e));
            responseVO.setStatus(CangoRspStatus.FAILURE);
        }
        return responseVO;
    }

    // update实例
    @RequestMapping("/updateInce")
    @ResponseBody
    public CangoResponseVO updateInstance(HttpServletRequest request, String params) {
        CangoResponseVO responseVO = new CangoResponseVO();
        try {
            ParamsVO paramVo = JSON.parseObject(URLDecoder.decode(params, "UTF-8"), ParamsVO.class);
            CangoInstances cangoInce = new CangoInstances();
            DatasourceBO sourceDataBO = datasourceService.findDatasourceBOById(paramVo.getSourceId());
            cangoInce.setSourceUserName(sourceDataBO.getUserName());
            cangoInce.setSourcePassword(sourceDataBO.getPassword());
            cangoInce.setSourceJDBCUrl(sourceDataBO.getJdbcUrl());
            cangoInce.setSourceType(sourceDataBO.getSourceType());
            if (paramVo.getIsRocketmq() == 0) {
                DatasourceBO targetDataBO = datasourceService.findDatasourceBOById(paramVo.getTargetId());
                cangoInce.setTargetUserName(targetDataBO.getUserName());
                cangoInce.setTargetPassword(targetDataBO.getPassword());
                cangoInce.setTargetJDBCUrl(targetDataBO.getJdbcUrl());
                cangoInce.setTargetType(targetDataBO.getSourceType());
            } else {
                cangoInce.setTopicname(paramVo.getTopicName());
                cangoInce.setNamesrvaddr(paramVo.getNameSrvAddr());
                cangoInce.setTargetType(DataBaseType.ROCKETMQ.getTypeName());
            }
            cangoInce.setTables(paramVo.getSourceTableName());
            cangoInce.setProjectName(paramVo.getProjectName());
            cangoInce.setMoveMode(paramVo.getMoveMode());
            if (DataBaseType.getDataBaseType(cangoInce.getSourceType()).equals(DataBaseType.MySql)) {
                String[] mysqlAdress = cangoInce.getSourceJDBCUrl().split("//")[1].split("/");
                cangoInce.setSourceDBname(mysqlAdress[1]);
                cangoInce.setSourceHost(mysqlAdress[0].split(":")[0]);
                cangoInce.setSourcePort(Integer.parseInt(mysqlAdress[0].split(":")[1]));
            }
            if (DataBaseType.getDataBaseType(cangoInce.getTargetType()).equals(DataBaseType.MySql)) {
                String[] mysqlAdress = cangoInce.getTargetJDBCUrl().split("//")[1].split("/");
                cangoInce.setTargetDBname(mysqlAdress[1]);
                cangoInce.setTargetHost(mysqlAdress[0].split(":")[0]);
                cangoInce.setTargetPort(Integer.parseInt(mysqlAdress[0].split(":")[1]));
            }
            cangoInce.setName(paramVo.getInstanceName());
            responseVO = cangoManagerService.updateCangoInce(cangoInce);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getMessage(e));
            responseVO.setFailMsg(ExceptionUtils.getMessage(e));
            responseVO.setStatus(CangoRspStatus.FAILURE);
        }
        return responseVO;
    }

}
